unit DFrame.DefaultLogger;

interface

uses
  Classes, SysUtils, DFrame.Logger, DFrame.LoggerFactory, DFrame.LoggedObject;

type

TDefaultLogger = class(TLoggerAdaptor)
protected
  FName : string;
  FBuffer : TStringBuilder;

  procedure prn(const text:string); virtual;
  procedure write(const texts :array of string; const t:Exception); virtual;
public
  constructor Create(name:String);
  destructor Destroy; override;

  function getName(): String; override;

  function isTraceEnabled():boolean; override;
  procedure trace(const msg:String); overload; override;
  procedure trace(const msg: String; const t: Exception); overload; override;

  function isDebugEnabled() : boolean; override;
  procedure debug(const msg: String); overload; override;
  procedure debug(const msg: String; const t: Exception); overload; override;

  function isInfoEnabled() : boolean; override;
  procedure info(const msg: String); overload; override;
  procedure info(const msg: String; const t: Exception); overload; override;

  function isWarnEnabled() : boolean; override;
  procedure warn(const msg: String); overload; override;
  procedure warn(const msg: String; const t: Exception); overload; override;

  function isErrorEnabled() : boolean; override;
  procedure error(const msg: String); overload; override;
  procedure error(const msg: String; const t: Exception); overload; override;

end;


TDefaultLoggerFactory = class(TInterfacedObject, ILoggerFactory)
  function getLogger(name:String):ILogger;
end;

implementation

uses
  Windows;

{ TDefaultLoggerFactory }

function TDefaultLoggerFactory.getLogger(name: String): ILogger;
begin
  Result := TDefaultLogger.Create(name);
end;


{ TDefaultLogger }

constructor TDefaultLogger.Create(name: String);
begin
  FName := name;
  FBuffer := TStringBuilder.Create(512);
end;

destructor TDefaultLogger.Destroy;
begin
  FreeAndNil(FBuffer);
  inherited;
end;

function TDefaultLogger.getName: String;
begin
  Result := FName;
end;

procedure TDefaultLogger.debug(const msg: String; const t: Exception);
begin
  write(['debug', FName, msg], t);
end;

procedure TDefaultLogger.debug(const msg: String);
begin
  write(['debug', FName, msg], nil);
end;

procedure TDefaultLogger.error(const msg: String; const t: Exception);
begin
  write(['error', FName, msg], t);
end;

procedure TDefaultLogger.error(const msg: String);
begin
  write(['error', FName, msg], nil);
end;

procedure TDefaultLogger.info(const msg: String; const t: Exception);
begin
  write(['info', FName, msg], t);
end;

procedure TDefaultLogger.info(const msg: String);
begin
  write(['info', FName, msg], nil);
end;

function TDefaultLogger.isDebugEnabled: boolean;
begin
  Result := true;
end;

function TDefaultLogger.isErrorEnabled: boolean;
begin
  Result := true;
end;

function TDefaultLogger.isInfoEnabled: boolean;
begin
  Result := true;
end;

function TDefaultLogger.isTraceEnabled: boolean;
begin
  Result := true;
end;

function TDefaultLogger.isWarnEnabled: boolean;
begin
  Result := true;
end;

procedure TDefaultLogger.prn(const text: string);
begin
  OutputDebugString(PChar(text));
end;

procedure TDefaultLogger.trace(const msg: String; const t: Exception);
begin
  write(['trace', FName, msg], t);
end;

procedure TDefaultLogger.trace(const msg: String);
begin
  write(['trace', FName, msg], nil);
end;

procedure TDefaultLogger.warn(const msg: String; const t: Exception);
begin
  write(['warn', FName, msg], t);
end;

procedure TDefaultLogger.warn(const msg: String);
begin
  write(['warn', FName, msg], nil);
end;

procedure TDefaultLogger.write(const texts: array of string; const t:Exception);
const
  SPLIT = ' ';
var
  I: Integer;
  e : Exception;
begin
  FBuffer.Append(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now));
  for I := 0 to length(texts) - 1 do begin
    FBuffer.Append(SPLIT);
    FBuffer.Append(texts[I]);
  end;
  e := t;
  while Assigned(e) do begin
    FBuffer.Append(SPLIT);
    FBuffer.Append(#13#10);
    FBuffer.Append(e.Message);
    FBuffer.Append(e.StackTrace);
    e := e.InnerException;
  end;
  prn(FBuffer.ToString());
  FBuffer.Length := 0;
end;

initialization
  {$IFDEF DEBUG}OutputDebugString('init default logger');{$ENDIF}

finalization
  {$IFDEF DEBUG}OutputDebugString('finalize default logger');{$ENDIF}

end.
